/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 商城模块
	/// module : mall
	/// </summary>
	public interface CNetMall : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction buyResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<BuyResultData>)wrapper;
                SC_buyResult(session, ref _wrapper.message);
                MessageWrapperPool<BuyResultData>.Put(_wrapper);
            };
            MessageFunction notifyMallRefresh_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyMallRefreshData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mall_notifyMallRefresh, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyMallRefresh(session, _wrapper.message.mallBuyCountRecords);
                MessageWrapperPool<NotifyMallRefreshData>.Put(_wrapper);
            };
            MessageFunction notifyMallStartSellTime_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyMallStartSellTimeData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mall_notifyMallStartSellTime, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyMallStartSellTime(session, _wrapper.message.mallStartSellTime);
                MessageWrapperPool<NotifyMallStartSellTimeData>.Put(_wrapper);
            };
            MessageFunction notifyPayInfo_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyPayInfoData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mall_notifyPayInfo, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyPayInfo(session, _wrapper.message.payCount);
                MessageWrapperPool<NotifyPayInfoData>.Put(_wrapper);
            };
            MessageFunction notifyMonthCard_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyMonthCardData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mall_notifyMonthCard, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyMonthCard(session, _wrapper.message.monthCard);
                MessageWrapperPool<NotifyMonthCardData>.Put(_wrapper);
            };
            MessageFunction notifyRecharge_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyRechargeData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mall_notifyRecharge, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyRecharge(session, _wrapper.message.notifyRechargePOD);
                MessageWrapperPool<NotifyRechargeData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.mall_buyResult, (session, package) => {
                	var result = MessageWrapperPool<BuyResultData>.Get();
                	result.Init(session, buyResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mall_notifyMallRefresh, (session, package) => {
                	var result = MessageWrapperPool<NotifyMallRefreshData>.Get();
                	result.Init(session, notifyMallRefresh_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mall_notifyMallStartSellTime, (session, package) => {
                	var result = MessageWrapperPool<NotifyMallStartSellTimeData>.Get();
                	result.Init(session, notifyMallStartSellTime_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mall_notifyPayInfo, (session, package) => {
                	var result = MessageWrapperPool<NotifyPayInfoData>.Get();
                	result.Init(session, notifyPayInfo_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mall_notifyMonthCard, (session, package) => {
                	var result = MessageWrapperPool<NotifyMonthCardData>.Get();
                	result.Init(session, notifyMonthCard_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mall_notifyRecharge, (session, package) => {
                	var result = MessageWrapperPool<NotifyRechargeData>.Get();
                	result.Init(session, notifyRecharge_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
		public void SC_buyResult(ISession session, ref BuyResultData message) 
		{
            _SC_buyResult(session, ref message);
		}
		
		public void _SC_buyResult(ISession session, ref BuyResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mall_buyResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.mall_buyResult, message.code);
			MsgAsyncAwaiter<BuyResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 商城物品购买次数限制记录,key=mallItemCid, value=次数
        /// </summary>
		protected void SC_notifyMallRefresh(ISession session, Dictionary<int, int> mallBuyCountRecords);
		/// <summary>
        /// 商城售卖时间更新
        /// </summary>
		protected void SC_notifyMallStartSellTime(ISession session, Dictionary<int, int> mallStartSellTime);
		/// <summary>
        /// 充值额外奖励
        /// </summary>
		protected void SC_notifyPayInfo(ISession session, Dictionary<int, int> payCount);
		/// <summary>
        /// 通知月卡数据
        /// </summary>
		protected void SC_notifyMonthCard(ISession session, Dictionary<int, int> monthCard);
		/// <summary>
        /// 通知充值成功
        /// </summary>
		protected void SC_notifyRecharge(ISession session, NotifyRechargePOD notifyRechargePOD);
#endregion
#region Server-side Interface
		/// <summary>
        /// 商城购买
        /// </summary>
    	public UniTask<BuyResultData> CS_buy(int mallItemCid, int num)
        {
            return _CS_buy(mallItemCid, num);
        }
        
        public UniTask<BuyResultData> _CS_buy(int mallItemCid, int num)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(BuyResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mall_buy, "Send->"+"Mall.CS_buy { "
				+ "mallItemCid="
				+ mallItemCid
				+ ", num="
				+ num
				+" }");
#endif
        	UniTask<BuyResultData> task = MsgAsyncAwaiter<BuyResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_buy(mallItemCid, num));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.mall_buyResult);
			return task;
        }
		
		public static SendPackage Pack_for_buy(int mallItemCid, int num) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mall_buy;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(mallItemCid);
			_out.Write_int(num);
			return si_p;
		}
#endregion
#region Messages
        public struct BuyResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public List<ItemShowPOD> getItems;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                getItems = _in.HasRemaining() ? _in.Read_list_pod<ItemShowPOD>(ItemShowPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mall_buyResult;}
            
            public override string ToString()
            {
                return "Mall.buyResult"+ ", code="+ code+ ", getItems="+ getItems.ToString<ItemShowPOD>();
            }
        }
        public struct NotifyMallRefreshData : IReceiveMessage {
	        public Dictionary<int, int> mallBuyCountRecords;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                mallBuyCountRecords = _in.HasRemaining() ? _in.Read_map_int_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mall_notifyMallRefresh;}
            
            public override string ToString()
            {
                return "Mall.notifyMallRefresh"+ ", mallBuyCountRecords="+ mallBuyCountRecords.ToString<int, int>();
            }
        }
        public struct NotifyMallStartSellTimeData : IReceiveMessage {
	        public Dictionary<int, int> mallStartSellTime;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                mallStartSellTime = _in.HasRemaining() ? _in.Read_map_int_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mall_notifyMallStartSellTime;}
            
            public override string ToString()
            {
                return "Mall.notifyMallStartSellTime"+ ", mallStartSellTime="+ mallStartSellTime.ToString<int, int>();
            }
        }
        public struct NotifyPayInfoData : IReceiveMessage {
	        public Dictionary<int, int> payCount;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                payCount = _in.HasRemaining() ? _in.Read_map_int_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mall_notifyPayInfo;}
            
            public override string ToString()
            {
                return "Mall.notifyPayInfo"+ ", payCount="+ payCount.ToString<int, int>();
            }
        }
        public struct NotifyMonthCardData : IReceiveMessage {
	        public Dictionary<int, int> monthCard;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                monthCard = _in.HasRemaining() ? _in.Read_map_int_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mall_notifyMonthCard;}
            
            public override string ToString()
            {
                return "Mall.notifyMonthCard"+ ", monthCard="+ monthCard.ToString<int, int>();
            }
        }
        public struct NotifyRechargeData : IReceiveMessage {
	        public NotifyRechargePOD notifyRechargePOD;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                notifyRechargePOD = _in.HasRemaining() ? _in.Read_pod<NotifyRechargePOD>(NotifyRechargePOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mall_notifyRecharge;}
            
            public override string ToString()
            {
                return "Mall.notifyRecharge"+ ", notifyRechargePOD="+ notifyRechargePOD;
            }
        }
    }
#endregion
}